#include <stdlib.h>
#include <stdio.h>

#include "header.h"

extern scm reg[256];
extern void *heap;
extern void *stack;

extern void *bytecode;
extern unsigned int place;
extern int code_length;

int execute(void) {
  unsigned char r1, r2, hh, ss;
  char sn;

  unsigned char *byte = bytecode;
  unsigned char *signed_byte = bytecode;
  
  while(place < code_length) {
    switch(byte[place++]) {
      //
    case 0x00:
      break;

      // 
    case 0x01:
      r1 = byte[place++];
      r2 = byte[place++];
#ifdef DISASSEMBLE
      printf("MOV R%d, R%d\n", r1, r2);
#else
#endif
      break;
    case 0x02:
      r1 = byte[place++];
      hh = byte[place++];
#ifdef DISASSEMBLE
      printf("MOV R%d, heap[%d]\n", r1, hh);
#else
#endif
      break;
    case 0x03:
      hh = byte[place++];
      r1 = byte[place++];
#ifdef DISASSEMBLE
      printf("MOV heap[%d], R%d\n", hh, r1);
#else
#endif
      break;
    case 0x04:
      r1 = byte[place++];
      ss = byte[place++];
#ifdef DISASSEMBLE
      printf("MOV R%d, stack[%d]\n", r1, ss);
#else
#endif
      break;
    case 0x05:
      ss = byte[place++];
      r1 = byte[place++];
#ifdef DISASSEMBLE
      printf("MOV stack[%d], R%d\n", ss, r1);
#else
#endif
      break;

      // stack

      // jumps
    case 0xB:
      sn = signed_byte[place++];
#ifdef DISASSEMBLE
      printf("JMP %d\n", sn);
#else
#endif
      break;

    case 0xFE:
#ifdef DISASSEMBLE
      printf("EXIT FAIL\n");
#else
#endif
      break;
      
    case 0xFF:
#ifdef DISASSEMBLE
      printf("EXIT OK\n");
#else
#endif
      break;
      
      //
    default:
      fprintf(stderr, "Unknown byte instruction %02x\n", byte[place-1]);
      return -1;
    }
  }

  fprintf(stderr, "Reached end of code\n");
  return 0;
}
